import Map from "ol/Map";
import {
  getMap,
  openlayersInit,
  destroyMap,
  addMapEventListener,
  removeMapEventListener,
  clearMapEventListener,
} from "./instance";
import { renderWMTSTileLayer } from "./addLayer";
import {
  fitViewByFeatures,
  fitViewByGeometryOrExtent,
  fitViewByQuery,
  getView,
  panTo,
} from "./view";
import {
  queryExtentByCoordinates,
  queryExtentByFeatures,
  queryExtentByQuery,
  transformExtentExpand,
  transformExtentOffset,
} from "./extent";
import {
  renderMarkerLayer,
  renderMarkers,
  showOrRenderMarkerLayer,
} from "./marker";
import {
  clearFeatures,
  queryFeatureAndLayerTypes,
  queryFeatureExist,
  queryFeatures,
  queryFeatureTypes,
  queryLayerExist,
  queryLayerTypes,
  removeFeatures,
  renderFeatureLayer,
  renderFeatures,
  setFeaturesVisible,
  showOrRenderFeatureLayer,
} from "./feature";
import { queryOverlay, removeOverlay, renderOverlay } from "./overlay";
import {
  showTianDiTuLayer,
  createTDTSatelliteLayers,
  _tileGrid,
  createTDTAllLayers,
  createTDTVectorLayers,
  createTDTDarkVectorLayers,
} from "./tianditu";
import {
  renderPolygonLayer,
  renderPolygons,
  showOrRenderPolygonLayer,
} from "./polygon";
import {
  renderPolylineLayer,
  renderPolylines,
  showOrRenderPolylineLayer,
} from "./polyline";
import {
  renderCircleLayer,
  renderCircles,
  showOrRenderCircleLayer,
} from "./circle";
import { renderClusterLayer, showOrRenderClusterLayer } from "./cluster";
import { renderHeatmapLayer, showOrRenderHeatmapLayer } from "./heatmap";
import { wgs84togcj02, gcj02toWgs84 } from "@utils";
import { renderImageLayer, showOrRenderImageLayer } from "./image";
import {
  renderWMSTileLayer,
  showOrRenderWMSTileLayer,
  showOrRenderWMTSTileLayer,
} from "./tile";
import { getDistance, getArea } from "./utils";
export {
  openlayersInit,
  destroyMap,
  createTDTSatelliteLayers,
  _tileGrid,
  createTDTAllLayers,
  createTDTVectorLayers,
  createTDTDarkVectorLayers,
};

// 地图 API
export interface MapAPI {
  map: Map; // 地图实例
  gcj02toWgs84: typeof gcj02toWgs84; // gcj02 转换 wgs84
  wgs84togcj02: typeof wgs84togcj02; // wgs84 转换 gcj02
  addMapEventListener: typeof addMapEventListener; // 添加地图事件监听
  removeMapEventListener: typeof removeMapEventListener; // 移除地图事件监听
  clearMapEventListener: typeof clearMapEventListener; // 清空地图事件监听
  getView: typeof getView; // 获取视图实例
  panTo: typeof panTo; // 移动地图视角
  queryExtentByCoordinates: typeof queryExtentByCoordinates; // 通过经纬度数组获取范围
  queryExtentByFeatures: typeof queryExtentByFeatures; // 通过元素获取范围
  queryExtentByQuery: typeof queryExtentByQuery; // 通过查询参数获取范围
  transformExtentOffset: typeof transformExtentOffset; // 范围偏移转换
  transformExtentExpand: typeof transformExtentExpand; // 范围扩张转换
  fitViewByGeometryOrExtent: typeof fitViewByGeometryOrExtent; // 根据几何图形或者边界调整视角
  fitViewByFeatures: typeof fitViewByFeatures; // 根据元素调整视角
  fitViewByQuery: typeof fitViewByQuery; // 通过查询调整视角
  renderMarkers: typeof renderMarkers; // 渲染点位
  renderMarkerLayer: typeof renderMarkerLayer; // 渲染点位图层 // TODO
  showOrRenderMarkerLayer: typeof showOrRenderMarkerLayer; // 显示或渲染点位图层
  renderPolygons: typeof renderPolygons; // 渲染多边形
  renderPolygonLayer: typeof renderPolygonLayer; // 渲染多边形图层
  showOrRenderPolygonLayer: typeof showOrRenderPolygonLayer; // 显示或渲染多边形图层
  renderPolylines: typeof renderPolylines; // 渲染折线
  renderPolylineLayer: typeof renderPolylineLayer; // 渲染折线图层
  showOrRenderPolylineLayer: typeof showOrRenderPolylineLayer; // 显示或渲染折线图层
  renderCircles: typeof renderCircles; // 渲染圆形
  renderCircleLayer: typeof renderCircleLayer; // 渲染圆形图层
  showOrRenderCircleLayer: typeof showOrRenderCircleLayer; // 显示或渲染圆形图层
  renderFeatures: typeof renderFeatures; // 渲染多种元素
  renderFeatureLayer: typeof renderFeatureLayer; // 渲染多种元素图层
  showOrRenderFeatureLayer: typeof showOrRenderFeatureLayer; // 显示或渲染元素图层
  renderClusterLayer: typeof renderClusterLayer; // 渲染点聚合图层
  showOrRenderClusterLayer: typeof showOrRenderClusterLayer; // 显示或者渲染点聚合图层
  renderHeatmapLayer: typeof renderHeatmapLayer; // 渲染热力图层
  showOrRenderHeatmapLayer: typeof showOrRenderHeatmapLayer; // 显示或渲染热力图层
  renderImageLayer: typeof renderImageLayer; // 渲染图片图层
  showOrRenderImageLayer: typeof showOrRenderImageLayer; // 显示或渲染图片图层
  renderWMSTileLayer: typeof renderWMSTileLayer; // 渲染 WMS 瓦片图层
  showOrRenderWMSTileLayer: typeof showOrRenderWMSTileLayer; // 显示或渲染 WMS 瓦片图层
  renderWMTSTileLayer: typeof renderWMTSTileLayer; // 渲染 WMTS 瓦片图层
  showOrRenderWMTSTileLayer: typeof showOrRenderWMTSTileLayer; // 显示或渲染 WMTS 瓦片图层
  renderOverlay: typeof renderOverlay; // 渲染地图弹窗
  queryOverlay: typeof queryOverlay; // 获取地图弹窗
  queryFeatures: typeof queryFeatures; // 查询元素
  setFeaturesVisible: typeof setFeaturesVisible; // 设置元素显隐
  removeOverlay: typeof removeOverlay; // 关闭地图弹窗
  removeFeatures: typeof removeFeatures; // 移除默认元素图层内容
  clearFeatures: typeof clearFeatures; // 清空默认元素图层内容
  queryFeatureTypes: typeof queryFeatureTypes; // 查询元素类型
  queryLayerTypes: typeof queryLayerTypes; // 查询图层类型
  queryFeatureAndLayerTypes: typeof queryFeatureAndLayerTypes; // 查询图层类型
  queryFeatureExist: typeof queryFeatureExist; // 查询元素是否存在
  queryLayerExist: typeof queryLayerExist; // 查询图层是否存在
  showTianDiTuLayer: typeof showTianDiTuLayer; // 显示天地图指定图层
  getDistance: typeof getDistance; // 获取两个坐标之间的距离，单位米
  getArea: typeof getArea; // 获取几何形状的面积，单位平方米
}

// 最大尝试次数
const MAX_COUNTER = 25;
/**
 * @description: 创建地图 API
 * @returns {Promise<MapAPI>}
 */
export const openlayersAPI = (): Promise<MapAPI> =>
  new Promise<MapAPI>((resolve, reject) => {
    let counter = 0;
    let interval: number | undefined | NodeJS.Timeout;
    const checked = () => {
      const mapInstance = getMap();
      if (counter > MAX_COUNTER) {
        if (typeof interval === "number") {
          clearInterval(interval);
        }
        reject(new Error("地图实例未初始化"));
      } else if (mapInstance instanceof Map) {
        const apis = {
          map: mapInstance,
          addMapEventListener,
          removeMapEventListener,
          clearMapEventListener,
          renderWMTSTileLayer,
          getView,
          panTo,
          queryExtentByCoordinates,
          queryExtentByFeatures,
          queryExtentByQuery,
          transformExtentOffset,
          transformExtentExpand,
          fitViewByGeometryOrExtent,
          fitViewByFeatures,
          fitViewByQuery,
          renderMarkers,
          renderMarkerLayer,
          removeFeatures,
          showOrRenderMarkerLayer,
          removeOverlay,
          clearFeatures,
          queryFeatureTypes,
          queryLayerTypes,
          queryFeatureAndLayerTypes,
          queryFeatureExist,
          queryLayerExist,
          showTianDiTuLayer,
          renderPolygons,
          renderPolygonLayer,
          showOrRenderPolygonLayer,
          renderPolylines,
          renderPolylineLayer,
          showOrRenderPolylineLayer,
          renderCircles,
          renderCircleLayer,
          showOrRenderCircleLayer,
          renderFeatures,
          renderFeatureLayer,
          showOrRenderFeatureLayer,
          renderClusterLayer,
          showOrRenderClusterLayer,
          renderHeatmapLayer,
          showOrRenderHeatmapLayer,
          renderImageLayer,
          showOrRenderImageLayer,
          renderWMSTileLayer,
          showOrRenderWMSTileLayer,
          showOrRenderWMTSTileLayer,
          renderOverlay,
          queryOverlay,
          queryFeatures,
          setFeaturesVisible,
          wgs84togcj02,
          gcj02toWgs84,
          getDistance,
          getArea,
        };
        if (typeof interval === "number") {
          clearInterval(interval);
        }
        resolve(apis);
      } else {
        console.log(`尝试初始化地图地${counter}次`);
        counter += 1;
      }
    };
    checked();
    if (counter > 0) {
      interval = setInterval(() => checked(), 250);
    }
  });
